package com.example.personblog.service;

import com.example.personblog.common.ResultEnum;
import com.example.personblog.entity.Post;
import com.example.personblog.exception.BusinessException;
import com.example.personblog.repository.PostRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.PageImpl;

import java.util.List;

@Service
public class PostService {

    @Autowired
    private PostRepository postRepository;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    private static final String VIEW_KEY = "post:view:"; // Redis中浏览量的key前缀
    private static final String LIKE_KEY = "post:like:";

    public List<Post> getAllPosts() {
        return postRepository.findAll();
    }

    public Post getPostById(Long id) {
        return postRepository.findById(id)
                .orElseThrow(() -> new BusinessException(ResultEnum.POST_NOT_EXIST));
    }

    @Transactional
    public Post createPost(Post post, Long userId) {
        post.setUserId(userId);
        return postRepository.save(post);
    }

    @Transactional
    public Post updatePost(Post post, Long userId) {
        Post existingPost = getPostById(post.getId());

        // 检查是否是帖子作者
        if (!existingPost.getUserId().equals(userId)) {
            throw new BusinessException(ResultEnum.POST_NO_PERMISSION);
        }

        existingPost.setTitle(post.getTitle());
        existingPost.setContent(post.getContent());
        existingPost.setStatus(post.getStatus());

        return postRepository.save(existingPost);
    }

    @Transactional
    public void deletePost(Long id, Long userId) {
        Post post = getPostById(id);

        // 检查是否是帖子作者
        if (!post.getUserId().equals(userId)) {
            throw new BusinessException(ResultEnum.POST_NO_PERMISSION);
        }

        postRepository.deleteById(id);
    }

    /**
     * 增加浏览量
     */
    @Transactional
    public void incrementViews(Long postId) {
        String viewKey = VIEW_KEY + postId;

        // 使用Redis的increment操作原子性地增加浏览量
        redisTemplate.opsForValue().increment(viewKey, 1);

        // 每增加10次浏览，同步一次到数据库
        Long views = redisTemplate.opsForValue().get(viewKey) != null
                ? Long.parseLong(redisTemplate.opsForValue().get(viewKey).toString())
                : 0;

        if (views % 10 == 0) {
            postRepository.updateViews(postId, views);
        }
    }

    /**
     * 获取文章浏览量
     */
    public Long getViews(Long postId) {
        String viewKey = VIEW_KEY + postId;
        Object views = redisTemplate.opsForValue().get(viewKey);
        if (views == null) {
            // 如果Redis中没有，从数据库获取并缓存
            Post post = postRepository.findById(postId)
                    .orElseThrow(() -> new BusinessException(ResultEnum.POST_NOT_EXIST));
            redisTemplate.opsForValue().set(viewKey, post.getViews().toString());
            return post.getViews();
        }
        return Long.parseLong(views.toString());
    }

    @Transactional
    public void incrementLikes(Long postId) {
        Post post = getPostById(postId);
        if (post != null) {
            post.setLikes(post.getLikes() + 1);
            postRepository.save(post);
        }
    }

    /**
     * 获取点赞数
     */
    public Long getLikeCount(Long postId) {
        Post post = getPostById(postId);
        return post != null ? post.getLikes() : 0L;
    }

    /**
     * 分页获取文章列表
     */
    public Page<Post> getPostsByPage(int page, int size, Integer status) {
        Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createTime"));

        // 使用JOIN FETCH查询
        List<Post> posts = postRepository.findPostsWithUser(status, pageable);
        long total = postRepository.countByStatus(status);

        return new PageImpl<>(posts, pageable, total);
    }

    /**
     * 搜索文章
     */
    public Page<Post> searchPosts(String keyword, int page, int size) {
        Pageable pageable = PageRequest.of(page, size, Sort.by("createTime").descending());
        return postRepository.searchPosts(keyword, pageable);
    }

    /**
     * 点赞/取消点赞
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean toggleLike(Long postId, Long userId) {
        String key = LIKE_KEY + postId;
        Boolean isMember = redisTemplate.opsForSet().isMember(key, userId.toString());

        if (Boolean.TRUE.equals(isMember)) {
            // 取消点赞
            redisTemplate.opsForSet().remove(key, userId.toString());
            postRepository.decrementLikes(postId);
            return false;
        } else {
            // 点赞
            redisTemplate.opsForSet().add(key, userId.toString());
            postRepository.incrementLikes(postId);
            return true;
        }
    }

    /**
     * 获取点赞状态
     */
    public boolean getLikeStatus(Long postId, Long userId) {
        String key = LIKE_KEY + postId;
        return Boolean.TRUE.equals(redisTemplate.opsForSet().isMember(key, userId.toString()));
    }
}